/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.cleaner;

import cz.mzk.kramerius.commons.DatastreamId;
import cz.mzk.kramerius.commons.Dom4jUtils;
import cz.mzk.kramerius.fedoraaccess.FedoraConnector;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.ws.soap.SOAPFaultException;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.XPath;

/**
 *
 * @author Martin Řehánek (rehan at mzk.cz)
 */
public class AbstractRemover {

    private static final Logger logger = Logger.getLogger(AbstractRemover.class.getName());
    private final FedoraConnector con;
    private final XPath pagePidsXpath = Dom4jUtils.createXPath("/rdf:RDF/rdf:Description/kramerius:hasPage/@rdf:resource");
    private final XPath internalPartPidsXpath = Dom4jUtils.createXPath("/rdf:RDF/rdf:Description/kramerius:hasIntCompPart/@rdf:resource");

    public AbstractRemover(FedoraConnector con) {
        this.con = con;
    }

    protected void removeInternalParts(String parentObjectPid) {
        List<String> internalPartPidList = findPidsOfInternalParts(parentObjectPid);
        System.out.println("internalParts: " + internalPartPidList.size());
        for (String internalPartPid : internalPartPidList) {
            System.out.println("internalPart pid: '" + internalPartPid + "'");
            purgeDigitalObject(internalPartPid);
            System.out.println("internalPart removed");
        }
    }

    protected void removePages(String parentObjectPid) {
        List<String> pagePidList = findPidsOfPages(parentObjectPid);
        System.out.println("pages: " + pagePidList.size());
        for (String pagePid : pagePidList) {
            System.out.println("page pid: '" + pagePid + "'");
            purgeDigitalObject(pagePid);
            System.out.println("page removed");
        }
    }

    private List<String> findPidsOfInternalParts(String parentObjectPid) {
        return findPidsOfReferencedEntities(parentObjectPid, internalPartPidsXpath);
    }

    private List<String> findPidsOfPages(String parentObjectPid) {
        return findPidsOfReferencedEntities(parentObjectPid, pagePidsXpath);
    }

    protected List<String> findPidsOfReferencedEntities(String parentObjectPid, XPath xpathToReferencedObjects) {
        try {
            Document relsExt = con.getXmlDatastreamDissemination(parentObjectPid, DatastreamId.RELS_EXT);
            List<Node> nodes = xpathToReferencedObjects.selectNodes(relsExt);
            return toPidList(nodes);
        } catch (SOAPFaultException ex) {
            logger.log(Level.WARNING, "Cannot disseminate {0} datastream for pid ''{1}''", new Object[]{DatastreamId.RELS_EXT.toString(), parentObjectPid});
            return Collections.EMPTY_LIST;
        }
    }

    protected void purgeDigitalObject(String pid) {
        //TODO: uncomment
        //System.out.println("removing '" + pid + "'");
        con.removeObject(pid, "cleaning repository");
    }

    private List<String> toPidList(List<Node> nodes) {
        List<String> pidList = new ArrayList<String>();
        String prefix = "info:fedora/";
        for (Node node : nodes) {
            String pidPrefixed = node.getText();
            String pid = unprefixString(pidPrefixed, prefix);
            pidList.add(pid);
        }
        return pidList;
    }

    private String unprefixString(String sourceString, String prefix) {
        int prefixSize = prefix.length();
        return sourceString.substring(prefixSize);
    }
}
